home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 June: Reference Library / Dev.CD Jun 99 RL Disk 1.toast / What's New / Development Kits / Mac_OS_USB_DDK_v1.2 / Examples / KeyboardModule / KeyIn.c < prev   
Encoding:
C/C++ Source or Header  |  1999-04-15  |  11.3 KB  |  492 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        KeyIn.c
  3.  
  4.     Contains:    ADB keyboard simulation (non-shim based).
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Copyright:    © 1998-1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10. */
  11.  
  12. /*
  13.  USB Keyboard Translation to Macintosh 
  14.  */
  15.  
  16. #include <Types.h>
  17. #include <Events.h>
  18. #include <Resources.h>
  19. #include <LowMem.h>
  20. #include <USB.h>
  21. #include "KeyboardModule.h"
  22.  
  23.  
  24. #define DOWN        0
  25. #define UP            1
  26.  
  27. #define TRUE        1
  28. #define FALSE        0
  29.  
  30. #define FakeADBAddr        16
  31. #define FakeKBDType        2        // this should be the same as the Apple extended keyboard for now
  32.  
  33. static UInt32    myKeyMAP[4];
  34. static UInt32    keyTransState;
  35. static Handle    handleKCHR;
  36. static UInt8*    KCHRptr;
  37.  
  38. typedef KeyMap * KeyMapPtr;
  39.  
  40. /* prototypes */
  41. Boolean KeyInArray(UInt8 key, UInt8 *array, UInt16 len);
  42. Boolean SetBit(UInt8 *bitmapArray, UInt16 index, Boolean value); 
  43. void  PostADBKeyToMac(UInt16 virtualKeycode, UInt8 state);
  44.  
  45. /* when we move to master interfaces we can get this stuff from LowMem.h */
  46. /* be sure to turn on DIRECT_LOWMEM_ACCESSORS */
  47. #define LMSetKbdVars(value) ((*(short *)0x0216) = (value))
  48. #define LMSetKeyLast(value) ((*(short *)0x0184) = (value))
  49. #define LMSetKeyTime(value) ((*(long *)0x0186) = (value))
  50. #define LMSetKeyRepTime(value) ((*(long *)0x018A) = (value))
  51. #define LMSetKeyMap(KeyMapValue)    BlockMove((Ptr)(KeyMapValue), (Ptr)0x0174, sizeof(KeyMap))
  52.  
  53.  
  54. // index represents USB keyboard usage value, content is Mac virtual keycode
  55. static UInt8    USBKMAP[256] = {  
  56.     0xFF,     /* 00 no event */        
  57.     0xFF,    /* 01 ErrorRollOver */    
  58.     0xFF,    /* 02 POSTFail */    
  59.     0xFF,    /* 03 ErrorUndefined */    
  60.     0x00,    /* 04 A */
  61.     0x0B,    /* 05 B */
  62.     0x08,    /* 06 C */
  63.     0x02,    /* 07 D */
  64.     0x0E,    /* 08 E */
  65.     0x03,    /* 09 F */
  66.     0x05,    /* 0A G */
  67.     0x04,    /* 0B H */
  68.     0x22,    /* 0C I */
  69.     0x26,    /* 0D J */
  70.     0x28,    /* 0E K */
  71.     0x25,    /* 0F L */
  72.  
  73.     0x2E,     /* 10 M */        
  74.     0x2D,    /* 11 N */    
  75.     0x1F,    /* 12 O */    
  76.     0x23,    /* 13 P */    
  77.     0x0C,    /* 14 Q */
  78.     0x0F,    /* 15 R */
  79.     0x01,    /* 16 S */
  80.     0x11,    /* 17 T */
  81.     0x20,    /* 18 U */
  82.     0x09,    /* 19 V */
  83.     0x0D,    /* 1A W */
  84.     0x07,    /* 1B X */
  85.     0x10,    /* 1C Y */
  86.     0x06,    /* 1D Z */
  87.     0x12,    /* 1E 1/! */
  88.     0x13,    /* 1F 2/@ */
  89.  
  90.     0x14,     /* 20 3 # */        
  91.     0x15,    /* 21 4 $ */    
  92.     0x17,    /* 22 5 % */    
  93.     0x16,    /* 23 6 ^ */    
  94.     0x1A,    /* 24 7 & */
  95.     0x1C,    /* 25 8 * */
  96.     0x19,    /* 26 9 ( */
  97.     0x1D,    /* 27 0 ) */
  98.     0x24,    /* 28 Return (Enter) */
  99.     0x35,    /* 29 ESC */
  100.     0x33,    /* 2A Delete (Backspace) */
  101.     0x30,    /* 2B Tab */
  102.     0x31,    /* 2C Spacebar */
  103.     0x1B,    /* 2D - _ */
  104.     0x18,    /* 2E = + */
  105.     0x21,    /* 2F [ { */
  106.  
  107.     0x1E,     /* 30 ] } */        
  108.     0x2A,    /* 31 \ | */    
  109.     0xFF,    /* 32 Non-US # and ~ (what?!!!) */    
  110.     0x29,    /* 33 ; : */    
  111.     0x27,    /* 34 ' " */
  112.     0x32,    /* 35 ` ~ */
  113.     0x2B,    /* 36 , < */
  114.     0x2F,    /* 37 . > */
  115.     0x2C,    /* 38 / ? */
  116.     0x39,    /* 39 Caps Lock */
  117.     0x7A,    /* 3A F1 */
  118.     0x78,    /* 3B F2 */
  119.     0x63,    /* 3C F3 */
  120.     0x76,    /* 3D F4 */
  121.     0x60,    /* 3E F5 */
  122.     0x61,    /* 3F F6 */
  123.  
  124.     0x62,     /* 40 F7 */        
  125.     0x64,    /* 41 F8 */    
  126.     0x65,    /* 42 F9 */    
  127.     0x6D,    /* 43 F10 */    
  128.     0x67,    /* 44 F11 */
  129.     0x6F,    /* 45 F12 */
  130.     0x69,    /* 46 F13/PrintScreen */
  131.     0x6B,    /* 47 F14/ScrollLock */
  132.     0x71,    /* 48 F15/Pause */                
  133.     0x72,    /* 49 Insert */
  134.     0x73,    /* 4A Home */
  135.     0x74,    /* 4B PageUp */
  136.     0x75,    /* 4C Delete Forward */
  137.     0x77,    /* 4D End */
  138.     0x79,    /* 4E PageDown */
  139.     0x7C,    /* 4F RightArrow */
  140.  
  141.     0x7B,     /* 50 LeftArrow */        
  142.     0x7D,    /* 51 DownArrow */    
  143.     0x7E,    /* 52 UpArrow */    
  144.     0x47,    /* 53 NumLock/Clear */    
  145.     0x4B,    /* 54 Keypad / */
  146.     0x43,    /* 55 Keypad * */
  147.     0x4E,    /* 56 Keypad - */
  148.     0x45,    /* 57 Keypad + */
  149.     0x4C,    /* 58 Keypad Enter */
  150.     0x53,    /* 59 Keypad 1 */
  151.     0x54,    /* 5A Keypad 2 */
  152.     0x55,    /* 5B Keypad 3 */
  153.     0x56,    /* 5C Keypad 4 */
  154.     0x57,    /* 5D Keypad 5 */
  155.     0x58,    /* 5E Keypad 6 */
  156.     0x59,    /* 5F Keypad 7 */
  157.  
  158.     0x5B,     /* 60 Keypad 8 */        
  159.     0x5C,    /* 61 Keypad 9 */    
  160.     0x52,    /* 62 Keypad 0 */    
  161.     0x41,    /* 63 Keypad . */    
  162.     0xFF,    /* 64 Non-US \ and  | (what ??!!) */
  163.     0x6E,    /* 65 ApplicationKey (not on a mac!)*/
  164.     0x7F,    /* 66 PowerKey  */
  165.     0x51,    /* 67 Keypad = */
  166.     0x69,    /* 68 F13 */
  167.     0x6B,    /* 69 F14 */
  168.     0x71,    /* 6A F15 */
  169.     0xFF,    /* 6B F16 */
  170.     0xFF,    /* 6C F17 */
  171.     0xFF,    /* 6D F18 */
  172.     0xFF,    /* 6E F19 */
  173.     0xFF,    /* 6F F20 */
  174.  
  175.     0x5B,     /* 70 F21 */        
  176.     0x5C,    /* 71 F22 */    
  177.     0x52,    /* 72 F23 */    
  178.     0x41,    /* 73 F24 */    
  179.     0xFF,    /* 74 Execute */
  180.     0xFF,    /* 75 Help */
  181.     0x7F,    /* 76 Menu */
  182.     0x4C,    /* 77 Select */
  183.     0x69,    /* 78 Stop */
  184.     0x6B,    /* 79 Again */
  185.     0x71,    /* 7A Undo */
  186.     0xFF,    /* 7B Cut */
  187.     0xFF,    /* 7C Copy */
  188.     0xFF,    /* 7D Paste */
  189.     0xFF,    /* 7E Find */
  190.     0xFF,    /* 7F Mute */
  191.     
  192.     0xFF,     /* 80 no event */        
  193.     0xFF,    /* 81 no event */    
  194.     0xFF,    /* 82 no event */    
  195.     0xFF,    /* 83 no event */    
  196.     0xFF,    /* 84 no event */
  197.     0xFF,    /* 85 no event */
  198.     0xFF,    /* 86 no event */
  199.     0xFF,    /* 87 no event */
  200.     0xFF,    /* 88 no event */
  201.     0xFF,    /* 89 no event */
  202.     0xFF,    /* 8A no event */
  203.     0xFF,    /* 8B no event */
  204.     0xFF,    /* 8C no event */
  205.     0xFF,    /* 8D no event */
  206.     0xFF,    /* 8E no event */
  207.     0xFF,    /* 8F no event */
  208.  
  209.     0xFF,     /* 90 no event */        
  210.     0xFF,    /* 91 no event */    
  211.     0xFF,    /* 92 no event */    
  212.     0xFF,    /* 93 no event */    
  213.     0xFF,    /* 94 no event */
  214.     0xFF,    /* 95 no event */
  215.     0xFF,    /* 96 no event */
  216.     0xFF,    /* 97 no event */
  217.     0xFF,    /* 98 no event */
  218.     0xFF,    /* 99 no event */
  219.     0xFF,    /* 9A no event */
  220.     0xFF,    /* 9B no event */
  221.     0xFF,    /* 9C no event */
  222.     0xFF,    /* 9D no event */
  223.     0xFF,    /* 9E no event */
  224.     0xFF,    /* 9F no event */
  225.  
  226.     0xFF,     /* A0 no event */        
  227.     0xFF,    /* A1 no event */    
  228.     0xFF,    /* A2 no event */    
  229.     0xFF,    /* A3 no event */    
  230.     0xFF,    /* A4 no event */
  231.     0xFF,    /* A5 no event */
  232.     0xFF,    /* A6 no event */
  233.     0xFF,    /* A7 no event */
  234.     0xFF,    /* A8 no event */
  235.     0xFF,    /* A9 no event */
  236.     0xFF,    /* AA no event */
  237.     0xFF,    /* AB no event */
  238.     0xFF,    /* AC no event */
  239.     0xFF,    /* AD no event */
  240.     0xFF,    /* AE no event */
  241.     0xFF,    /* AF no event */
  242.  
  243.     0xFF,     /* B0 no event */        
  244.     0xFF,    /* B1 no event */    
  245.     0xFF,    /* B2 no event */    
  246.     0xFF,    /* B3 no event */    
  247.     0xFF,    /* B4 no event */
  248.     0xFF,    /* B5 no event */
  249.     0xFF,    /* B6 no event */
  250.     0xFF,    /* B7 no event */
  251.     0xFF,    /* B8 no event */
  252.     0xFF,    /* B9 no event */
  253.     0xFF,    /* BA no event */
  254.     0xFF,    /* BB no event */
  255.     0xFF,    /* BC no event */
  256.     0xFF,    /* BD no event */
  257.     0xFF,    /* BE no event */
  258.     0xFF,    /* BF no event */
  259.  
  260.     0xFF,     /* C0 no event */        
  261.     0xFF,    /* C1 no event */    
  262.     0xFF,    /* C2 no event */    
  263.     0xFF,    /* C3 no event */    
  264.     0xFF,    /* C4 no event */
  265.     0xFF,    /* C5 no event */
  266.     0xFF,    /* C6 no event */
  267.     0xFF,    /* C7 no event */
  268.     0xFF,    /* C8 no event */
  269.     0xFF,    /* C9 no event */
  270.     0xFF,    /* CA no event */
  271.     0xFF,    /* CB no event */
  272.     0xFF,    /* CC no event */
  273.     0xFF,    /* CD no event */
  274.     0xFF,    /* CE no event */
  275.     0xFF,    /* CF no event */
  276.  
  277.     0xFF,     /* D0 no event */        
  278.     0xFF,    /* D1 no event */    
  279.     0xFF,    /* D2 no event */    
  280.     0xFF,    /* D3 no event */    
  281.     0xFF,    /* D4 no event */
  282.     0xFF,    /* D5 no event */
  283.     0xFF,    /* D6 no event */
  284.     0xFF,    /* D7 no event */
  285.     0xFF,    /* D8 no event */
  286.     0xFF,    /* D9 no event */
  287.     0xFF,    /* DA no event */
  288.     0xFF,    /* DB no event */
  289.     0xFF,    /* DC no event */
  290.     0xFF,    /* DD no event */
  291.     0xFF,    /* DE no event */
  292.     0xFF,    /* DF no event */
  293.  
  294.     0x3B,     /* E0 left control key */        
  295.     0x38,    /* E1 left shift key key */    
  296.     0x3A,    /* E2 left alt/option key */    
  297.     0x37,    /* E3 left GUI (windows/cmd) key */    
  298.     
  299.     0x3B,    /* E4 right control key */ 
  300.     0x38,    /* E5 right shift key key */ 
  301.     0x3A,    /* E6 right alt/option key */ 
  302.     0x37,    /* E7 right GUI (windows/cmd) key */
  303.     0xFF,    /* E8 no event */
  304.     0xFF,    /* E9 no event */
  305.     0xFF,    /* EA no event */
  306.     0xFF,    /* EB no event */
  307.     0xFF,    /* EC no event */
  308.     0xFF,    /* ED no event */
  309.     0xFF,    /* EE no event */
  310.     0xFF,    /* EF no event */
  311.     
  312.     0xFF,     /* F0 no event */        
  313.     0xFF,    /* F1 no event */    
  314.     0xFF,    /* F2 no event */    
  315.     0xFF,    /* F3 no event */    
  316.     0xFF,    /* F4 no event */
  317.     0xFF,    /* F5 no event */
  318.     0xFF,    /* F6 no event */
  319.     0xFF,    /* F7 no event */
  320.     0xFF,    /* F8 no event */
  321.     0xFF,    /* F9 no event */
  322.     0xFF,    /* FA no event */
  323.     0xFF,    /* FB no event */
  324.     0xFF,    /* FC no event */
  325.     0xFF,    /* FD no event */
  326.     0xFF,    /* FE no event */
  327.     0xFF,    /* FF no event */
  328. };
  329.         
  330. void
  331. InitUSBKeyboard()
  332. {
  333.     handleKCHR = GetResource('KCHR',0);    // US keyboard mapping (handled differently by ADB Mgr)
  334.     HLock(handleKCHR);
  335.     KCHRptr = (UInt8 *)*handleKCHR;
  336. }
  337.  
  338.  
  339.  
  340. void PostUSBKeyToMac(UInt16 rawUSBkey)
  341. {
  342. static    UInt8    oldLEDState = 0x00;
  343. static    UInt8    newLEDState = 0x00;
  344.  
  345. static    UInt8    capsLockState = 0x00;
  346. static    UInt8    numLockState = 0x00;
  347. static    UInt8    scrollLockState = 0x00;
  348.  
  349. register UInt8    virtualKeycode, keystate;
  350.  
  351.     
  352.     if (KCHRptr == 0)
  353.     {
  354.         InitUSBKeyboard();
  355.     }
  356.     
  357.     keystate = (rawUSBkey & 0x8000) ? UP : DOWN;
  358.     rawUSBkey &= 0x0FF;
  359.     
  360.     if (keystate == DOWN)
  361.     {
  362.         newLEDState = oldLEDState;
  363.         
  364.         switch (rawUSBkey)
  365.         {
  366. // Note:  This switch statement is being left it to make it easy to add "toggling" keys in the future.
  367. //        it used to support toggled numlock & scroll lock...  It doesn't anymore.
  368.             case kUSBCapsLockKey:
  369.                 newLEDState ^= (1 << kCapsLockLED);
  370.                 keystate = (newLEDState & (1 << kCapsLockLED)) ? DOWN : UP;
  371.                 break;
  372.         }
  373.         
  374.         if (newLEDState != oldLEDState)
  375.         {
  376.             oldLEDState = newLEDState;
  377.             USBHIDControlDevice(kHIDSetLEDStateByBits, &newLEDState);
  378.         }
  379.     }
  380.     else
  381.     {
  382.         switch (rawUSBkey)
  383.         {
  384. // Note:  This switch statement is being left it to make it easy to add "toggling" keys in the future.
  385.             case kUSBCapsLockKey:
  386.                 return;
  387.                 break;
  388.         }
  389.     }
  390.     
  391.     // look up rawUSBkey in KMAP resource to get virtual keycode
  392.     if (rawUSBkey < sizeof(USBKMAP))
  393.     {
  394.         virtualKeycode = USBKMAP[rawUSBkey];
  395.     } 
  396.     else 
  397.     {
  398. //        DebugStr("\pPostUSBKeyToMac: Need bigger KMAP table");
  399.         virtualKeycode = 0xFF;
  400.     }
  401.  
  402.     PostADBKeyToMac(virtualKeycode, keystate);
  403.     if (virtualKeycode == 0x7F)
  404.         PostADBKeyToMac(virtualKeycode, keystate);
  405. }
  406.  
  407. void 
  408. PostADBKeyToMac(UInt16 virtualKeycode, UInt8 state)
  409. {
  410.     UInt32    keyEventMsg;
  411.     
  412.     if (virtualKeycode > 127) return;  // not handled by MacOS!
  413.     
  414.     // stop repeating
  415.     LMSetKeyLast(0);
  416.     LMSetKbdVars(0);
  417.     
  418.     // update our keymap
  419.     SetBit((UInt8 *)myKeyMAP, virtualKeycode, state == DOWN ? 1 : 0);
  420.     LMSetKeyMap(&myKeyMAP);
  421.  
  422.     // set this keyboard as the last keyboard
  423.     LMSetKbdLast(FakeADBAddr);
  424.     LMSetKbdType(FakeKBDType);
  425.     
  426.     // call KeyTrans to get character code
  427.     virtualKeycode |= ((myKeyMAP[1]<<9) & 0x00FE00) | ((myKeyMAP[1]>>7) & 0x0100) | ((state==UP) ? 0x080 : 0);
  428.     keyEventMsg = KeyTranslate(KCHRptr, virtualKeycode , &keyTransState);
  429.     virtualKeycode &= 0x7F;
  430.     
  431.     if (keyEventMsg & 0xFFFF0000) {
  432.         // post event
  433.         UInt32 event =(keyEventMsg & 0xFF000000) | ((FakeADBAddr << 16) & 0x0FF0000) | ((virtualKeycode << 8) & 0x0FF00)  | ((keyEventMsg>>16) & 0x0FF);
  434.         if (state == DOWN){
  435.             UInt32 ticks = TickCount();
  436.             LMSetKeyTime(ticks);
  437.             LMSetKeyRepTime(ticks);
  438.             LMSetKeyLast(event & 0x0FFFF);
  439.             LMSetKbdVars((event>>16) & 0x0FFFF);
  440.         }        
  441.         PostEvent((state == DOWN ? keyDown : keyUp), event);
  442.     }
  443.     if (keyEventMsg & 0x0000FFFF) {
  444.         // post event
  445.         UInt32 event =((keyEventMsg<<16) & 0xFF000000) | ((FakeADBAddr << 16) & 0x0FF0000) | ((virtualKeycode << 8) & 0x0FF00)  | (keyEventMsg & 0x0FF);
  446.         if (state == DOWN){
  447.             UInt32 ticks = TickCount();
  448.             LMSetKeyTime(ticks);
  449.             LMSetKeyRepTime(ticks);
  450.             LMSetKeyLast(event & 0x0FFFF);
  451.             LMSetKbdVars((event>>16) & 0x0FFFF);
  452.         }        
  453.         PostEvent((state == DOWN ? keyDown : keyUp), event);
  454.     }
  455. }
  456.  
  457. // Sets the bitmapArray[index] to value
  458. // returns old value;
  459. Boolean
  460. SetBit(UInt8 *bitmapArray, UInt16 index, Boolean value)
  461. {    
  462.     UInt32    mask = 0x1 << (index % 8 );
  463.     Boolean    oldVal;
  464.     
  465.     oldVal = (bitmapArray[index/8] & mask) ? TRUE : FALSE;
  466.     
  467.     if (value){
  468.         bitmapArray[index/8] |= mask;
  469.     }else{
  470.         bitmapArray[index/8] &= ~mask;
  471.     }
  472.     
  473.     return (oldVal);
  474. }
  475.  
  476. void USBDemoKeyIn(UInt32 refcon, void * theData)
  477. {
  478. #pragma unused (refcon)
  479.  
  480. USBHIDDataPtr    pTheKeyboardData;
  481. register        UInt8    i;
  482.  
  483.     pTheKeyboardData = (USBHIDDataPtr)theData;
  484.     for (i=0; i<pTheKeyboardData->kbd.keycount; i++)
  485.     {
  486.         // no shim installed, let's just post some Macintosh keyevents
  487.         PostUSBKeyToMac(pTheKeyboardData->kbd.usbkeycode[i]);
  488.     }
  489.  
  490. }
  491.  
  492.